﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ValidationFramework.Reflection
{
	public abstract class CachedInfoBase : ICachedReflectionInfo
	{
		// --- Constructors

		/// <summary>
		/// Initialize a new instance of <see cref="InfoDescriptor"/>. Exposed for testing purposes.
		/// </summary>
		/// <param name="infoTypeTypeHandle"></param>
		/// <param name="name">The name of the <see cref="InfoDescriptor"/>.</param>
		/// <exception cref="ArgumentNullException"><paramref name="name"/> is null.</exception>
		/// <exception cref="ArgumentException"><paramref name="name"/> is a <see cref="string.Empty"/>.</exception>
		/// <exclude/>
		protected CachedInfoBase(RuntimeTypeHandle infoTypeTypeHandle, string name)
		{
			Guard.ArgumentNotNullOrEmptyString(name, "name");
			Guard.ArgumentNotNull(infoTypeTypeHandle, "memberTypeHandle");
			
			MemberTypeHandle = infoTypeTypeHandle;
			Name = name;
		}

		// --- Properties

	    /// <summary>
		/// Gets the name of the <see cref="InfoDescriptor"/>.
		/// </summary>
		public string Name
	    {
	        get;
	        private set;
	    }

	    /// <summary>
		/// Gets the <see cref="RuntimeTypeHandle"/> for the member this <see cref="InfoDescriptor"/> describes.
		/// </summary>
		/// <remarks>For a <see cref="PropertyDescriptor"/> this will be the <see cref="RuntimeTypeHandle"/> for the return <see cref="Type"/> of the get. For a <see cref="ParameterDescriptor"/> this will be the <see cref="RuntimeTypeHandle"/> for the <see cref="Type"/> of the <see langword="parameter"/>.</remarks>
		public RuntimeTypeHandle MemberTypeHandle
		{
			get;
			private set;
		}

		// --- Methods

		/// <summary>
		/// Get the value for this <see cref="InfoDescriptor"/>.
		/// </summary>
		/// <param name="instance">The object on which to extract the field value. If a <see cref="InfoDescriptor"/> is static, this argument is ignored.</param>
		/// <returns>The value for the <see cref="InfoDescriptor"/>.</returns>
		public abstract object GetValue(object instance);
	}
}
